////////////////////////////////////////////////////////////////////
// Programme de conversion des images de Chrono Cross
////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////
// Nemesis pour Terminus Traduction (tt_nemesis@yahoo.fr)
// Date de création :		02/08/03
// Dernière modification :	10/08/03
////////////////////////////////////////////////////////////////////

// Entete
#include "Tim.h"

// Constantes des TIM (4bits/pixel,8bits/pixel)
_int8 TIM_CODE[]={0x08,0x09};
int TIM_ENTETE[]={12,12};
int TIM_PALETTE[]={20,20};
int TIM_TAILLE[]={52,532};
int TIM_LARGHAUT[]={60,540};
int TIM_DONNEES[]={64,544};

// Constantes des BMP
int BMP_TAILLE[]={2,2};
int BMP_ENTETE[]={10,10};
int BMP_LARGHAUT[]={18,18};
int BMP_BPP[]={28,28};
int BMP_PALETTE[]={54,54};
_int32 BMP_DONNEES[]={118,1078};

// Constantes communes
int TIP_COULEURS[]={16,256};
_int32 TIP_BPP[]={4,8};

// Entete des BMP 4bit/pixel avec palette
// les 0xFF marque les zones variables
unsigned _int8 BMP_ENTETE_4[] = {
	0x42,0x4D,				// Type de fichier (BM)
	0xFF,0xFF,0xFF,0xFF,	// Taille en octets du fichier
	0x00,0x00,0x00,0x00,	// Rien
	0xFF,0xFF,0xFF,0xFF,	// Offset de l'image (118 ou 1078)
	0x28,0x00,0x00,0x00,	// Taille de l'entête (40)
	0xFF,0xFF,0xFF,0xFF,	// Largeur
	0xFF,0xFF,0xFF,0xFF,	// Hauteur
	0x01,0x00,				// Nombre de plans (1)
	0xFF,0x00,				// Nombre de bits/pixel (4 ou 8)
	0x00,0x00,0x00,0x00,	// Compression (aucune)
	0x00,0x00,0x00,0x00,	// Taille de l'image (inutile)
	0x00,0x00,0x00,0x00,	// Résolution horizontale
	0x00,0x00,0x00,0x00,	// Résolution verticale
	0x00,0x00,0x00,0x00,	// Couleurs (palette entière)
	0x00,0x00,0x00,0x00,	// Couleurs principales (aucune)
};

/*------------------------------------------------------------------
  Conversion TIM->BMP d'un fichier
--------------------------------------------------------------------
 <- entree : chemin partiel du fichier TIM à convertir
------------------------------------------------------------------*/
void Tim_to_Bmp (char* entree)
{
	// Fichier et dossier
	char *dossier;
	char *fich;
	// Dossier complet
	char dossier_complet[TIM_NOM_MAX];
	// Fichier Tim à convertir
	FILE *tim_f;
	int type;
	// Fichier Bmp en sortie
	FILE *bmp_f;
	// Nom du fichier (chemin)
	char *fichier;
	char fich_complet[TIM_NOM_MAX];
	// Variables temporaires
	_int32 temp;
	// Propriétés de l'image
	unsigned _int16 hauteur,largeur;
	unsigned _int32 taille,tim_taille;
	// Palette de couleur
	unsigned _int16 couleur;
	unsigned _int8 composantes[4];
	int c;
	// Donnees
	unsigned _int8 o;
	_int32 l,i;

	Main_Message_S("Conversion TIM->BMP de %s... ",entree,OK);

	// Décomposition dossier/fichiers
	dossier=strtok(entree,SEPARATEUR);
	if (dossier[0]==NEUTRE)
		dossier[0]=0;
	fich=strtok(NULL,SEPARATEUR);

	// Recherche du fichier TIM
	sprintf(dossier_complet,"%s%s",DIR_FICH_IN,dossier);
	Fichier_Cherche(dossier_complet,fich,EXT_TIM,&fichier);
	// Ouverture du fichier TIM
	sprintf(fich_complet,"%s%s",dossier_complet,fichier);
	tim_f=fopen(fich_complet,"rb");

	// Fichier existant ?
	if (tim_f==NULL)
		Main_Message_S("Impossible d'ouvrir le fichier.\n","",ER);
	else {
		// Ouverture du fichier BMP pour écrasement
		strcpy(&fich_complet[strlen(fich_complet)-3],EXT_BMP);
		bmp_f=fopen(fich_complet,"wb");
		// Ecriture de l'entête
		fwrite(BMP_ENTETE_4,sizeof(BMP_ENTETE_4),1,bmp_f);
		fclose(bmp_f);
		// Réouverture pour modifications
		bmp_f=fopen(fich_complet,"r+b");
		// Récupération du type de TIM (4bpp|8bpp)
		fseek(tim_f,TIM_TYPE,SEEK_SET);
		if(fgetc(tim_f)==TIM_CODE[0])
			type=TIM_4BPP;
		else
			type=TIM_8BPP;
		// Ecriture du nombre de bits par pixel
		fseek(bmp_f,BMP_BPP[type],SEEK_SET);
		fwrite(&TIP_BPP[type],sizeof(_int32),1,bmp_f);
		// Ecriture de la taille d'entête
		fseek(bmp_f,BMP_ENTETE[type],SEEK_SET);
		fwrite(&BMP_DONNEES[type],sizeof(_int32),1,bmp_f);
		// Récupération de la largeur
		fseek(tim_f,TIM_LARGHAUT[type],SEEK_SET);
		fseek(bmp_f,BMP_LARGHAUT[type],SEEK_SET);
		fread(&largeur,sizeof(_int16),1,tim_f);
		largeur*=2;
		temp=largeur*8/TIP_BPP[type];
		fwrite(&temp,sizeof(_int32),1,bmp_f);
		// Récupération de la hauteur
		fread(&hauteur,sizeof(_int16),1,tim_f);
		temp=hauteur;
		fwrite(&temp,sizeof(_int32),1,bmp_f);
		// Récupération et conversion de la palette
		fseek(tim_f,TIM_PALETTE[type],SEEK_SET);
		fseek(bmp_f,BMP_PALETTE[type],SEEK_SET);
		composantes[3]=0x00;
		for(c=0;c<TIP_COULEURS[type];c++) {
			fread(&couleur,sizeof(_int16),1,tim_f);
			composantes[0]=8*(couleur>>10);			// Bleu
			composantes[1]=8*((couleur>>5) & 0x1F);	// Vert
			composantes[2]=8*(couleur & 0x1F);		// Rouge
			fwrite(&composantes,sizeof(_int8),4,bmp_f);
		}
		// Taille de l'image
		fseek(bmp_f,BMP_TAILLE[type],SEEK_SET);
		taille=largeur*hauteur+BMP_DONNEES[type];
		fwrite(&taille,sizeof(_int32),1,bmp_f);
		// Taille réelle du fichier TIM
		fseek(tim_f,0L,SEEK_END);
		tim_taille=ftell(tim_f);
		// Copie des données
		fseek(bmp_f,BMP_DONNEES[type],SEEK_SET);
		for(l=hauteur-1;l>=0;l--) {
			fseek(tim_f,TIM_DONNEES[type]+l*largeur,SEEK_SET);
			for(i=0;i<largeur;i++) {
				o=fgetc(tim_f);
				if (type==TIM_4BPP)
					o=(o%16)*16+(o>>4);
				fputc(o,bmp_f);
			}
			// Imposé par le format BMP
			// largeur en octets=multiple de 4
			for(i=0;i<(4-largeur%4)%4;i++)
				fputc(0,bmp_f);
		}
		// Fermeture des fichiers
		fclose(bmp_f);
		fclose(tim_f);
	}

	Main_OK();
}

/*------------------------------------------------------------------
  Conversion BMP->TIM d'un fichier
--------------------------------------------------------------------
 <- entree : chemin partiel du fichier BMP à reconvertir
------------------------------------------------------------------*/
void Bmp_to_Tim (char* entree)
{
	// Fichier et dossier
	char *dossier;
	char *fich;
	// Dossier complet
	char dossier_complet[TIM_NOM_MAX];
	// Fichier Tim de base et final
	FILE *tim_in_f;
	FILE *tim_out_f;
	int type;
	// Fichier Bmp à convertir
	FILE *bmp_f;
	// Nom du fichier (chemin)
	char fich_complet[TIM_NOM_MAX];
	char *fichier;
	// Offset du fichier BMP
	unsigned _int32 bmp_donnees;
	// Entete
	unsigned _int8 entete[TIM_DONNEES_MAX];
	// Propriétés de l'image
	unsigned _int16 hauteur;
	unsigned _int16 largeur,largeur2;
	// Donnees
	unsigned _int8 o;
	_int32 l,i;

	Main_Message_S("Conversion BMP->TIM de %s... ",entree,OK);

	// Décomposition dossier/fichiers
	dossier=strtok(entree,SEPARATEUR);
	if (dossier[0]==NEUTRE)
		dossier[0]=0;
	fich=strtok(NULL,SEPARATEUR);

	// Recherche du fichier TIM d'origine
	sprintf(dossier_complet,"%s%s",DIR_FICH_IN,dossier);
	Fichier_Cherche(dossier_complet,fich,EXT_TIM,&fichier);
	// Ouverture du fichier TIM
	sprintf(fich_complet,"%s%s",dossier_complet,fichier);
	tim_in_f=fopen(fich_complet,"rb");

	// Recherche du fichier BMP
	sprintf(dossier_complet,"%s%s",DIR_FICH_OUT,dossier);
	Fichier_Cherche(dossier_complet,fich,EXT_BMP,&fichier);
	// Ouverture du fichier BMP
	sprintf(fich_complet,"%s%s",dossier_complet,fichier);
	bmp_f=fopen(fich_complet,"rb");

	// Fichiers existants ?
	if (bmp_f==NULL || tim_in_f==NULL)
		Main_Message_S("Impossible d'ouvrir le fichier.\n","",ER);
	else {
		// Ouverture du fichier TIM
		strcpy(&fich_complet[strlen(fich_complet)-3],EXT_TIM);
		tim_out_f=fopen(fich_complet,"wb");
		// Type de fichier TIM
		fseek(tim_in_f,TIM_TYPE,SEEK_SET);
		if(fgetc(tim_in_f)==TIM_CODE[0])
			type=TIM_4BPP;
		else
			type=TIM_8BPP;
		// Copie de l'entête
		fseek(tim_in_f,0L,SEEK_SET);
		fread(entete,sizeof(char),TIM_DONNEES[type],tim_in_f);
		fwrite(entete,sizeof(char),TIM_DONNEES[type],tim_out_f);
		// Récupération de l'offset des données
		fseek(bmp_f,BMP_ENTETE[type],SEEK_SET);
		fread(&bmp_donnees,sizeof(_int32),1,bmp_f);
		// Récupération de la largeur
		fseek(tim_in_f,TIM_LARGHAUT[type],SEEK_SET);
		fread(&largeur,sizeof(_int16),1,tim_in_f);
		largeur*=2;
		// Récupération de la hauteur
		fread(&hauteur,sizeof(_int16),1,tim_in_f);
		// Calcul de la pseudo-largeur
		// pour le fichier BMP
		largeur2=largeur+(4-largeur%4)%4;
		// Copie des données
		fseek(tim_out_f,TIM_DONNEES[type],SEEK_SET);
		for(l=hauteur-1;l>=0;l--) {
			fseek(bmp_f,bmp_donnees+l*largeur2,SEEK_SET);
			for(i=0;i<largeur;i++) {
				o=fgetc(bmp_f);
				if (type==TIM_4BPP)
					o=(o%16)*16+(o>>4);
				fputc(o,tim_out_f);
			}
		}
		// Fermeture des fichiers
		fclose(bmp_f);
		fclose(tim_out_f);
		fclose(tim_in_f);
	}

	Main_OK();
}